package cn.lg.soar.system.api.handler.translate;

import cn.lg.soar.common.util.trans.TranslateHelpUtils;
import cn.lg.soar.common.util.trans.handler.ITranslateHandler;
import cn.lg.soar.common.util.trans.model.TranslateContext;
import cn.lg.soar.system.api.model.DictDTO;
import cn.lg.soar.system.api.service.IDictApi;
import com.github.benmanes.caffeine.cache.Cache;
import com.github.benmanes.caffeine.cache.Caffeine;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Component;

import java.lang.annotation.Annotation;
import java.time.Duration;
import java.util.HashMap;
import java.util.Map;

/**
 * @author luguoxiang
 * @date 2022/6/11
 * 开源项目：https://gitee.com/lgx1992/lg-soar 求star！请给我star！请帮我点个star！
 */
@Component
public class TranslateByDictHandler implements ITranslateHandler<Object> {

    private final static Cache<Annotation, Map<Integer, String>> CACHE = Caffeine.newBuilder()
            .initialCapacity(16)
            .maximumSize(1024)
            .expireAfterWrite(Duration.ofSeconds(60))
            .build();

    private final static Cache<Annotation, Map<String, Integer>> TOJAVA_CACHE = Caffeine.newBuilder()
            .initialCapacity(16)
            .maximumSize(1024)
            .expireAfterWrite(Duration.ofSeconds(60))
            .build();

    @Autowired
    protected IDictApi dictApi;

    public  Map<Integer, String> getMap(Annotation annotation) {
        return CACHE.get(annotation, key -> {
            TranslateByDict dict = (TranslateByDict) annotation;
            return dictApi.labelMapByType(dict.value());
        });
    }

    @Override
    public Object convertByJava(Object javaValue, Annotation annotation, TranslateContext<Object> context) {
        Map<Integer, String> map = getMap(annotation);
        String text = map.get(javaValue);
        if (text != null) {
            return text;
        }
        return TranslateHelpUtils.mapper(javaValue, map);
    }

    @Override
    public Object convertToJava(Object value, Annotation annotation, TranslateContext<Object> context) {
        Map<String, Integer> map = TOJAVA_CACHE.get(annotation, key -> {
            Map<Integer, String> map1 = getMap(annotation);
            Map<String, Integer> rmap = new HashMap<>(map1.size());
            map1.forEach((k, v) -> rmap.put(v, k));
            return rmap;
        });
        Class<?> javaType = context.getJavaType();
        String strValue = value.toString();
        Integer integer = map.get(strValue);
        if (integer != null) {
            return integer;
        }
        Object o = TranslateHelpUtils.remapper(javaType, strValue, map::get);
        if (o != null) {
            return o;
        }
        return null;
    }
}
